Skip to content

Feature/add wincon gui#24

Merged
FeFFe1996 merged 12 commits into
mainfrom
feature/addWinconGui
Jan 14, 2026
Merged

Feature/add wincon gui#24
FeFFe1996 merged 12 commits into
mainfrom
feature/addWinconGui

Conversation

@FeFFe1996

@FeFFe1996 FeFFe1996 commented Jan 14, 2026

Copy link
Copy Markdown

win con in gui game

Summary by CodeRabbit

  • New Features

    • HUD now shows each player's current points.
    • Players earn points for successful moves.
    • Automatic win detection evaluates scores and displays a win dialog, halting further turns when a winner is found.
  • Breaking Changes

    • Removed direct public setters/getters for certain player and movement properties; external code must no longer rely on them.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Jan 14, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Adds HUD score display and win detection: new currentPointLabel and winConLabel FXML bindings; controller increments player score after arrivals, deduplicates locations, checks win condition via doesPlayerWin(), and updates the UI/turn flow when a winner is found.

Changes

Cohort / File(s) Change Summary
FXML: HUD & Dialog
src/main/resources/travelGame.fxml
Adds "Points:" label and currentPointLabel binding; introduces winConLabel DialogPane in the bottom layout.
Controller: Score, Win Logic & Helpers
src/main/java/org/example/TravelGameController.java
Adds Label currentPointLabel and DialogPane winConLabel fields; increments player score after arrivals; adds doesPlayerWin() and distinctLocationsById(List<Location>); invokes win check and updates UI/won state during move/journey flows.
Model/API: Player & Movement accessors removed
src/main/java/org/example/player.java, src/main/java/org/example/playerMovement.java
Removes setPlayerName(String) and setPlayerCredits(int) from Player; removes getTransDiceCount() from playerMovement (breaks external callers relying on these setters/getter).

Sequence Diagram(s)

sequenceDiagram
    participant Player
    participant Controller
    participant GameState
    participant UI

    Player->>Controller: performMove(destination)
    Controller->>GameState: recordArrival(player, destination)
    Controller->>GameState: incrementScore(player)
    Controller->>Controller: doesPlayerWin()
    alt winnerFound
        Controller->>UI: update winConLabel (announce winner)
        Controller->>UI: update currentPointLabel
        Controller->>GameState: set wonGame flag
    else noWinner
        Controller->>UI: update currentPointLabel
        Controller->>GameState: continue turn flow
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • Feature/add wincon gui #24 — Very similar edits adding winConLabel, currentPointLabel, doesPlayerWin(), and distinctLocationsById() to TravelGameController and FXML.
  • Feature/player movement #16 — Changes involving playerMovement.getTransDiceCount(); this PR removes that getter, indicating a direct API conflict.
  • Feature/javafx #8 — Earlier JavaFX controller/FXML wiring that this PR extends with score and win logic.

Poem

🐰 I hopped through code and left a trail,
Points now glitter on the HUD's pale veil.
A dialog cheers the winning run,
I nibble carrots when the game is won.
Hop, skip, debug — victory is done! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a win condition GUI feature with new UI elements, score tracking, and win detection logic.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings


📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 54a0ac1 and 9fbc151.

📒 Files selected for processing (2)
  • src/main/java/org/example/player.java
  • src/main/java/org/example/playerMovement.java

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/org/example/TravelGameController.java (1)

353-360: Missing score increment in doContinueJourney when player arrives.

The score is correctly incremented here in doMove when a player arrives at their destination. However, doContinueJourney (lines 445-446) also handles arrival but does not call managed.increaseScore() or doesPlayerWin(). A player completing their journey via continuation will not receive points and the win condition won't be checked.

Proposed fix for doContinueJourney
             if (managed.isTravelling()) {
                 logList.getItems().add(
                     "➡ " + safeName(managed)
                         + " fortsätter mot " + targetName
                         + " (rolled=" + journey.getDistanceMoved()
                         + ", remaining=" + journey.getRemainingDistance() + ")"
                 );
             } else {
                 logList.getItems().add("✅ " + safeName(managed) + " kom fram till " + targetName + "!");
+                managed.increaseScore();
             }

             tx.commit();
             players.set(currentPlayerIndex, managed);

-            if (!managed.isTravelling() && !wonGame) {
+            if (!managed.isTravelling()) {
+                doesPlayerWin();
+            }
+            if (!managed.isTravelling() && !wonGame) {
                 currentPlayerIndex = (currentPlayerIndex + 1) % players.size();
             }
🤖 Fix all issues with AI agents
In `@src/main/java/org/example/TravelGameController.java`:
- Around line 378-386: In doesPlayerWin(), stop the loop after the first winner
is found to avoid overwriting winConLabel and multiple state changes: after
setting wonGame = true and updating winConLabel with player.getPlayerName(),
break out of the for loop (or return from the method) so only the first matching
Traveler (from players) wins; also remove the System.out.println debug call and
replace it with a proper logger call (or delete it) to use production logging
instead of stdout.
🧹 Nitpick comments (2)
src/main/java/org/example/TravelGameController.java (1)

28-28: Consider using a Label instead of DialogPane for the win message.

DialogPane is typically used as the content root inside a Dialog or Alert, not as a standalone element in a layout. While this may work functionally, a Label would be more idiomatic for displaying a simple win message. You could also hide it initially and make it visible when a winner is declared.

src/main/resources/travelGame.fxml (1)

82-82: Consider visibility management for the win dialog.

The DialogPane is always present in the layout. Since it starts empty, users may see an empty styled box. Consider either:

  • Setting visible="false" initially and toggling it in the controller when a winner is found
  • Using a Label with visible="false" as a simpler alternative
-                    <DialogPane fx:id="winConLabel" style="-fx-font-size: 20px; -fx-font-weight: bold;"/>
+                    <Label fx:id="winConLabel" visible="false" style="-fx-font-size: 20px; -fx-font-weight: bold; -fx-text-fill: gold;"/>

Then in the controller:

winConLabel.setText(player.getPlayerName() + " Wins the game. Congratulations");
winConLabel.setVisible(true);
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f18d925 and f4e0f69.

📒 Files selected for processing (2)
  • src/main/java/org/example/TravelGameController.java
  • src/main/resources/travelGame.fxml
🔇 Additional comments (2)
src/main/java/org/example/TravelGameController.java (1)

48-48: LGTM - Score display integration.

The currentPointLabel binding and HUD update logic correctly displays the current player's score.

Also applies to: 264-264

src/main/resources/travelGame.fxml (1)

69-70: LGTM - Points label addition.

The "Points:" label and currentPointLabel follow the same pattern as the other HUD elements (Credits, Turn) and are correctly bound.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +378 to +386
private void doesPlayerWin() {
for (Traveler player : players) {
if (player.checkScore()) {
wonGame = true;
System.out.println(player.getPlayerName() + " Wins the game. Congratulations");
winConLabel.setContentText(player.getPlayerName() + " Wins the game. Congratulations");
}
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Loop continues after finding a winner; includes debug statement.

Two issues:

  1. The loop doesn't return or break after setting wonGame = true. If multiple players meet the win condition simultaneously, winConLabel will be overwritten multiple times.
  2. System.out.println should be removed or replaced with proper logging for production code.
Proposed fix
     private void doesPlayerWin() {
         for (Traveler player : players) {
             if (player.checkScore()) {
                 wonGame = true;
-                System.out.println(player.getPlayerName() + " Wins the game. Congratulations");
                 winConLabel.setContentText(player.getPlayerName() + " Wins the game. Congratulations");
+                return;
             }
         }
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private void doesPlayerWin() {
for (Traveler player : players) {
if (player.checkScore()) {
wonGame = true;
System.out.println(player.getPlayerName() + " Wins the game. Congratulations");
winConLabel.setContentText(player.getPlayerName() + " Wins the game. Congratulations");
}
}
}
private void doesPlayerWin() {
for (Traveler player : players) {
if (player.checkScore()) {
wonGame = true;
winConLabel.setContentText(player.getPlayerName() + " Wins the game. Congratulations");
return;
}
}
}
🤖 Prompt for AI Agents
In `@src/main/java/org/example/TravelGameController.java` around lines 378 - 386,
In doesPlayerWin(), stop the loop after the first winner is found to avoid
overwriting winConLabel and multiple state changes: after setting wonGame = true
and updating winConLabel with player.getPlayerName(), break out of the for loop
(or return from the method) so only the first matching Traveler (from players)
wins; also remove the System.out.println debug call and replace it with a proper
logger call (or delete it) to use production logging instead of stdout.

# Conflicts:
#	src/main/java/org/example/TravelGameController.java
# Conflicts:
#	src/main/java/org/example/TravelGameController.java

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@src/main/java/org/example/TravelGameController.java`:
- Around line 570-574: doContinueJourney() currently calls doesPlayerWin()
before tx.commit(), unlike doMove() which calls doesPlayerWin() after
committing; move the doesPlayerWin() invocation in doContinueJourney() to after
tx.commit() and after the players list is refreshed/updated so the win check
uses committed state and up-to-date player entities (ensure wonGame/UI updates
only happen post-commit).
- Around line 521-529: Remove the dead private helper
distinctLocationsById(List<Location>) since it is unused; delete the method
declaration (private List<Location> distinctLocationsById(...)) from
TravelGameController and ensure there are no remaining references to it
elsewhere; no functional changes needed because updateGraphicsWithMoves()
already handles deduplication with .distinct().
♻️ Duplicate comments (1)
src/main/java/org/example/TravelGameController.java (1)

510-518: Loop continues after finding a winner; includes debug statement.

The issues previously identified remain unaddressed:

  1. The loop doesn't return or break after setting wonGame = true, so if multiple players meet the win condition, winConLabel will be overwritten.
  2. System.out.println is debug code that should be removed for production.
Proposed fix
     private void doesPlayerWin() {
         for (Traveler player : players) {
             if (player.checkScore()) {
                 wonGame = true;
-                System.out.println(player.getPlayerName() + " Wins the game. Congratulations");
                 winConLabel.setContentText(player.getPlayerName() + " Wins the game. Congratulations");
+                return;
             }
         }
     }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7865809 and 54a0ac1.

📒 Files selected for processing (2)
  • src/main/java/org/example/TravelGameController.java
  • src/main/resources/travelGame.fxml
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/resources/travelGame.fxml
🔇 Additional comments (3)
src/main/java/org/example/TravelGameController.java (3)

11-11: LGTM!

The new imports and FXML field bindings for winConLabel (DialogPane) and currentPointLabel (Label) are correctly declared and align with the UI additions in the FXML file.

Also applies to: 30-30, 49-49


352-352: LGTM!

The score display follows the established pattern for HUD updates.


490-499: LGTM!

The score increment and win check integration is correctly placed: score increases only on arrival, win check occurs after commit, and turn progression is appropriately guarded by !wonGame.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +521 to +529
private List<Location> distinctLocationsById(List<Location> locations) {
java.util.Map<Long, Location> byId = new java.util.LinkedHashMap<>();
for (Location l : locations) {
if (l != null && l.getId() != null) {
byId.putIfAbsent(l.getId(), l);
}
}
return new java.util.ArrayList<>(byId.values());
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Search for all usages of distinctLocationsById in Java files
rg -n "distinctLocationsById" --type=java

Repository: ithsjava25/project-jpa-grupp-4-g

Length of output: 208


🏁 Script executed:

# Check the actual file content around lines 521-529 to verify the method definition
sed -n '515,535p' src/main/java/org/example/TravelGameController.java | cat -n

Repository: ithsjava25/project-jpa-grupp-4-g

Length of output: 921


🏁 Script executed:

# Check updateGraphicsWithMoves method around line 434 to see if it uses .distinct()
sed -n '430,445p' src/main/java/org/example/TravelGameController.java | cat -n

Repository: ithsjava25/project-jpa-grupp-4-g

Length of output: 621


Remove unused method distinctLocationsById().

This method is defined at lines 521-529 but is never called anywhere in the codebase. The similar deduplication logic in updateGraphicsWithMoves() uses the stream .distinct() method instead, making this dead code that should be removed.

🤖 Prompt for AI Agents
In `@src/main/java/org/example/TravelGameController.java` around lines 521 - 529,
Remove the dead private helper distinctLocationsById(List<Location>) since it is
unused; delete the method declaration (private List<Location>
distinctLocationsById(...)) from TravelGameController and ensure there are no
remaining references to it elsewhere; no functional changes needed because
updateGraphicsWithMoves() already handles deduplication with .distinct().

Comment on lines +570 to 574
managed.increaseScore();
doesPlayerWin();
}

tx.commit();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Inconsistent placement of doesPlayerWin() relative to transaction commit.

In doContinueJourney(), doesPlayerWin() is called before tx.commit() (line 574), whereas in doMove() it's called after the commit (line 495). This inconsistency could lead to issues:

  • If the transaction rolls back after doesPlayerWin() sets wonGame = true and updates the UI, the game state becomes inconsistent.
  • The players list isn't updated until line 575, so doesPlayerWin() may check stale entity references.
Proposed fix: Move win check after commit for consistency
             } else {
                 logList.getItems().add("✅ " + safeName(managed) + " kom fram till " + targetName + "!");
                 managed.increaseScore();
-                doesPlayerWin();
             }

             tx.commit();
             players.set(currentPlayerIndex, managed);
+            
+            if (!managed.isTravelling()) {
+                doesPlayerWin();
+            }

             if (!managed.isTravelling() && !wonGame) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
managed.increaseScore();
doesPlayerWin();
}
tx.commit();
} else {
logList.getItems().add("✅ " + safeName(managed) + " kom fram till " + targetName + "!");
managed.increaseScore();
}
tx.commit();
players.set(currentPlayerIndex, managed);
if (!managed.isTravelling()) {
doesPlayerWin();
}
if (!managed.isTravelling() && !wonGame) {
🤖 Prompt for AI Agents
In `@src/main/java/org/example/TravelGameController.java` around lines 570 - 574,
doContinueJourney() currently calls doesPlayerWin() before tx.commit(), unlike
doMove() which calls doesPlayerWin() after committing; move the doesPlayerWin()
invocation in doContinueJourney() to after tx.commit() and after the players
list is refreshed/updated so the win check uses committed state and up-to-date
player entities (ensure wonGame/UI updates only happen post-commit).

@FeFFe1996
FeFFe1996 merged commit 4f84037 into main Jan 14, 2026
1 of 2 checks passed
@FeFFe1996
FeFFe1996 deleted the feature/addWinconGui branch January 14, 2026 12:29
@coderabbitai coderabbitai Bot mentioned this pull request Jan 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant